package com.designoutput.utils
{	
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.Stage;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;

	public class HitTestUtils
	{
		public static function hitTestPoint(displayObject:DisplayObject, point:Point):Boolean {
			if(displayObject.stage == null)
				return false;
			
			var stage:Stage = displayObject.stage;
			
			var bounds:Rectangle = displayObject.getBounds(stage);
			if(bounds.width == 0 || bounds.height == 0)
				return false;
			
			var drawMatrix:Matrix = displayObject.transform.concatenatedMatrix;
			drawMatrix.translate(-bounds.x, -bounds.y);
			
			var displayObjectBitmapData:BitmapData = new BitmapData(Math.ceil(bounds.width), Math.ceil(bounds.height), true, 0);
			displayObjectBitmapData.draw(displayObject, drawMatrix);
			
			var pixel:uint = displayObjectBitmapData.getPixel32(point.x - bounds.x, point.y - bounds.y);
			return (pixel >> 24 & 0xFF) > 0;
		}
		
		public static function hitTestRectangle(displayObject:DisplayObject, testRectangle:Rectangle):Boolean {
			if(displayObject.stage == null)
				return false;
						
			var stage:Stage = displayObject.stage;
			
			if(testRectangle.width == 0 || testRectangle.height == 0)
				return false;
			
			var bounds:Rectangle = displayObject.getBounds(stage);
			if(bounds.width == 0 || bounds.height == 0)
				return false;
			
			var intersection:Rectangle = bounds.intersection(testRectangle);
			intersection.inflate(1, 1);
			if(intersection.width == 0 || intersection.height == 0)
				return false;
			
			var drawMatrix:Matrix = displayObject.transform.concatenatedMatrix;
			drawMatrix.translate(-intersection.x, -intersection.y);
			
			var displayObjectBitmapData:BitmapData = new BitmapData(Math.ceil(intersection.width), Math.ceil(intersection.height), true, 0);
			displayObjectBitmapData.draw(displayObject, drawMatrix);
				
			var testBitmapData:BitmapData = new BitmapData(Math.ceil(testRectangle.width), Math.ceil(testRectangle.height), true, 0);
			testBitmapData.floodFill(0, 0, 0xFF000000);
			
			return displayObjectBitmapData.hitTest(intersection.topLeft, 1, testBitmapData, testRectangle.topLeft, 1);
		}
		
		public static function hitTestBitmapData(displayObject:DisplayObject, testBitmapData:BitmapData, testPosition:Point):Boolean {
			if(displayObject.stage == null)
				return false;
			
			var stage:Stage = displayObject.stage;
									
			var bounds:Rectangle = displayObject.getBounds(stage);
			if(bounds.width == 0 || bounds.height == 0)
				return false;
			
			var testBounds:Rectangle = testBitmapData.rect.clone();
			testBounds.offsetPoint(testPosition);
				
			var intersection:Rectangle = bounds.intersection(testBounds);
			if(intersection.width == 0 || intersection.height == 0)
				return false;
						
			var drawMatrix:Matrix = displayObject.transform.concatenatedMatrix;
			drawMatrix.translate(-intersection.x, -intersection.y);
			
			var displayObjectBitmapData:BitmapData = new BitmapData(Math.ceil(intersection.width), Math.ceil(intersection.height), true, 0);
			displayObjectBitmapData.draw(displayObject, drawMatrix);
			
			return displayObjectBitmapData.hitTest(intersection.topLeft, 1, testBitmapData, testPosition, 1);
		}
	}
}